<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <link rel="stylesheet" href="./index.css" />
    </head>
    <body>
        <button id="play">暂停/播放</button>
        <script src="./js/index.js"></script>
        <script>
            const arr = [7, 4, 2, 6, 1, 0, 5, 8, 3];
            const sortCanvas = new SortCanvas({
                data: arr,
                layoutConfig: {
                    baseY: 350,
                    baseX: 200,
                },
            });

            const animateFunc = sortCanvas.compiler(mergeSort);
            animateFunc(arr, 0, arr.length - 1);
            sortCanvas.run();

            bindEvent(sortCanvas);

            function bubbleSort(arr) {
                for (let i = 0; i < arr.length; i++) {
                    for (let j = 0; j < arr.length - i - 1; j++) {
                        if (arr[j] > arr[j + 1]) {
                            // opt @swap(j, j + 1) speed=10
                            const tmp = arr[j];
                            arr[j] = arr[j + 1];
                            arr[j + 1] = tmp;
                        } else {
                            // opt @show(j, j + 1) speed=10
                            // opt @back(j, j + 1) speed=10
                        }
                    }
                }
                return arr;
            }

            function insertSort(arr) {
                for (let i = 1; i < arr.length; i++) {
                    let j = i - 1;
                    const tmp = arr[i];
                    // opt focus(i)
                    while (j >= 0 && tmp < arr[j]) {
                        // opt moveto(j, j + 1)
                        arr[j + 1] = arr[j];
                        j--;
                    }
                    // opt focus:cancel()
                    arr[j + 1] = tmp;
                }
                return arr;
            }

            function selectSort(arr) {
                for (let i = 0, k = 0; i < arr.length; i++, k = i) {
                    // opt @show(i)
                    for (let j = i + 1; j < arr.length; j++) {
                        // opt @show(j)
                        if (arr[k] > arr[j]) {
                            // opt @back(k)
                            k = j;
                        } else {
                            // opt @back(j)
                        }
                    }
                    if (i != k) {
                        // opt @swap(i, k)
                        const tmp = arr[i];
                        arr[i] = arr[k];
                        arr[k] = tmp;
                    }
                    //
                }
                return arr;
            }

            function mergeSort(arr) {
                const len = arr.length;
                let res = [];
                let gap, start;
                for (gap = 1; gap < len * 2; gap *= 2) {
                    for (start = 0; start < len; start += gap * 2) {
                        let low = start;
                        let mid = start + gap < len ? start + gap : len;
                        let high =
                            start + gap * 2 < len ? start + gap * 2 : len;

                        let start1 = low,
                            end1 = mid;
                        let start2 = mid,
                            end2 = high;
                        // opt group(low -> mid - 1)
                        // opt group(mid -> high - 1)
                        // opt @show(low -> high - 1) speed=10
                        while (start1 < end1 && start2 < end2) {
                            res[low++] =
                                arr[start1] < arr[start2]
                                    ? arr[start1++]
                                    : arr[start2++];
                        }
                        while (start1 < end1) {
                            res[low++] = arr[start1++];
                        }
                        while (start2 < end2) {
                            res[low++] = arr[start2++];
                        }
                    }
                    // opt @back() speed=10
                    const tmp = res;
                    res = arr;
                    arr = tmp;
                }
                res = arr;
                return res;
            }

            // 快排 不稳定
            function quickSort(arr, left, right) {
                if (left >= right) return;
                let reference = arr[left];
                // opt @show(left) speed=10
                let i = left + 1,
                    j = right;
                // opt group(left + 1 -> right)
                while (i < j) {
                    while (i < j && arr[j] >= reference) {
                        // opt @show(j) speed=10
                        // opt @back(j) speed=10
                        j--;
                    }
                    // opt @show(j) speed=10

                    while (i < j && arr[i] <= reference) {
                        // opt @show(i) speed=10
                        // opt @back(i) speed=10
                        i++;
                    }
                    // opt @show(i) speed=10

                    if (i < j) {
                        // opt @swap(i, j) speed=10
                        const tmp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = tmp;
                    }
                }
                // opt group(left)
                // opt group(left + 1 -> i)
                // opt group(i + 1 -> right)
                // opt @swap(left, i) speed=10
                // opt sleep(100)
                arr[left] = arr[i];
                arr[i] = reference;
                // opt group:cancel()
                quickSort(arr, left, i - 1);
                quickSort(arr, i + 1, right);
            }

            function bindEvent(sortCanvas) {
                const playBtn = document.getElementById("play");
                playBtn.addEventListener("click", () => {
                    sortCanvas.pause = !sortCanvas.pause;
                    console.log("暂停", sortCanvas.pause, sortCanvas);
                });
            }
        </script>
    </body>
</html>
